package simpleGeom;

import java.io.BufferedWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;

import processing.core.PGraphics;

public class Box3D extends Rect2D{

public float z1;
public float z2;

public Box3D(){
	
}

public Box3D(float x1,float y1,float z1,float x2,float y2,float z2){
	this.x1=x1;
	this.y1=y1;
	this.z1=z1;
	this.x2=x2;
	this.y2=y2;
	this.z2=z2;
}
public Box3D(double x1,double y1,double z1,double x2,double y2,double z2){
	this.x1=(float)x1;
	this.y1=(float)y1;
	this.z1=(float)z1;
	this.x2=(float)x2;
	this.y2=(float)y2;
	this.z2=(float)z2;
}
public Box3D(Box3D b){
	this.x1=b.getX1();
	this.y1=b.getY1();
	this.z1=b.getZ1();
	this.x2=b.getX2();;
	this.y2=b.getY2();
	this.z2=b.getZ2();
}

public void display3D(PGraphics g3d){
	g3d.pushMatrix();
	g3d.translate(this.getCenterX(), this.getCenterY(),this.getCenterZ());
	g3d.box(this.getDimX(),this.getDimY(),this.getDimZ());
	g3d.popMatrix();
}
public void reOrient(){
	if (x1>x2){
		float tmp=x1;
		x1=x2;
		x2=tmp;
	}
	if (y1>y2){
		float tmp=y1;
		y1=y2;
		y2=tmp;
	}
	if (z1>z2){
		float tmp=z1;
		z1=z2;
		z2=tmp;
	}
}
public float getDimZ(){
	return z2-z1;
}
public void add( Box3D box3D){
	this.x1=Math.min(box3D.x1, x1);
	this.y1=Math.min(box3D.y1, y1);
	this.z1=Math.min(box3D.z1, z1);
	
	this.x2=Math.max(box3D.x2, x2);
	this.y2=Math.max(box3D.y2, y2);
	this.z2=Math.max(box3D.z2, z2);
}
public void scaleAroundCenter(float s){
	float cX=this.getCenterX();
	float cY=this.getCenterY();
	float cZ=this.getCenterZ();
	float dX=this.getDimX()*s*0.5f;
	float dY=this.getDimY()*s*0.5f;
	float dZ=this.getDimZ()*s*0.5f;
	this.x1=cX-dX;
	this.x2=cX+dX;
	this.y1=cY-dY;
	this.y2=cY+dY;
	this.z1=cZ-dZ;
	this.z2=cZ+dZ;
}
public void mult(float sx,float sy,float sz){
	this.x1*=sx;
	this.x2*=sx;
	this.y1*=sy;
	this.y2*=sy;
	this.z1*=sz;
	this.z2*=sz;
}
public float getCenterZ(){
	return (z1+z2)*0.5f;
}
public Vec3D getCenter(){
	 return new Vec3D(getCenterX(),getCenterY(),getCenterZ());
}
public Vec3D getDimensions(){
	return new Vec3D(getDimX(),getDimY(),getDimZ());
}
public float getMaxDimension(){
	return Math.max(super.getMaxDimension(), getDimZ());
}

public float getZ1() {
	return z1;
}

public void setZ1(float z1) {
	this.z1 = z1;
}

public float getZ2() {
	return z2;
}
public float getInnerDistance(float x,float y,float z){
	float minX=Math.min(Math.abs(x-x1),Math.abs(x-x2));
	float minY=Math.min(Math.abs(y-y1),Math.abs(y-y2));
	float minZ=Math.min(Math.abs(z-z1),Math.abs(z-z2));
	float minD=Math.min(minX, minY);
	minD=Math.min(minD, minZ);
	return minD;
}

public void setZ2(float z2) {
	this.z2 = z2;
}
public void offset(float offset){
	x1-=offset;
	y1-=offset;
	z1-=offset;
	x2+=offset;
	y2+=offset;
	z2+=offset;
}
public Box3D getOffsetBox(float offset){
	return new Box3D(x1-offset,y1-offset,z1-offset,x2+offset,y2+offset,z2+offset);
}
public float getOverlapVolume(Box3D r){
	
	float oY=getOverlap(r.getY1(),r.getY2(),getY1(),getY2());
	if (oY<=0)return 0;
	
	float oX=getOverlap(r.getX1(),r.getX2(),getX1(),getX2());
	if (oX<=0)return 0;
	
	float oZ=getOverlap(r.getZ1(),r.getZ2(),getZ1(),getZ2());
	if (oZ<=0)return 0;
	
	return oX*oY*oZ;
}
public float getVolume(){
	return Math.abs(getDimX()*getDimY()*getDimZ());
}
public float getOverlapVolume(HasBounds3D r){
	
	return getOverlapVolume(r.getBounds3D());
	
}
public boolean isOverlap(float x1,float y1,float z1,float x2,float y2,float z2){
	float oY=getOverlap(y1,y2,getY1(),getY2());
	if (oY<=0)return false;
	float oX=getOverlap(x1,x2,getX1(),getX2());
	if (oX<=0)return false;
	float oZ=getOverlap(z1,z2,getZ1(),getZ2());
	if (oZ<=0)return false;
	return true;
}
public boolean isOverlap(Box3D r){
	float oY=getOverlap(r.getY1(),r.getY2(),getY1(),getY2());
	if (oY<=0)return false;
	float oX=getOverlap(r.getX1(),r.getX2(),getX1(),getX2());
	if (oX<=0)return false;
	float oZ=getOverlap(r.getZ1(),r.getZ2(),getZ1(),getZ2());
	if (oZ<=0)return false;
	return true;
}
public int saveObj(BufferedWriter writer,int i){
	try {
		writer.write("v "+x1+" "+y1+" "+z1);
		writer.newLine();
		writer.write("v "+x2+" "+y1+" "+z1);
		writer.newLine();
		writer.write("v "+x2+" "+y2+" "+z1);
		writer.newLine();
		writer.write("v "+x1+" "+y2+" "+z1);
		writer.newLine();
		writer.write("v "+x1+" "+y1+" "+z2);
		writer.newLine();
		writer.write("v "+x2+" "+y1+" "+z2);
		writer.newLine();
		writer.write("v "+x2+" "+y2+" "+z2);
		writer.newLine();
		writer.write("v "+x1+" "+y2+" "+z2);
		writer.newLine();
		writer.write("f "+(i+4)+" "+(i+3)+" "+(i+2)+" "+(i+1));
		writer.newLine();
		writer.write("f "+(i+1)+" "+(i+2)+" "+(i+6)+" "+(i+5));
		writer.newLine();
		writer.write("f "+(i+2)+" "+(i+3)+" "+(i+7)+" "+(i+6));
		writer.newLine();
		writer.write("f "+(i+3)+" "+(i+4)+" "+(i+8)+" "+(i+7));
		writer.newLine();
		writer.write("f "+(i+4)+" "+(i+1)+" "+(i+5)+" "+(i+8));
		writer.newLine();
		writer.write("f "+(i+5)+" "+(i+6)+" "+(i+7)+" "+(i+8));
		writer.newLine();
		return i+8;
	} catch (IOException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
	return i;
}
@Override
public String toString() {
	// TODO Auto-generated method stub
	return "x1:"+x1+" y1:"+y1+" z1:"+z1+" dX:"+getDimX()+" dY:"+getDimY()+" dZ:"+getDimZ();
}
public String toStringCorners(){
	return "_"+x1+"_"+y1+"_"+z1+"_"+x2+"_"+y2+"_"+z2;
}
public boolean contains(float x,float y,float z){
	if (x<x2&&x>=x1 && y<y2&&y>=y1 && z<z2&&z>=z1)return true;
	return false;
}
public boolean contains(HasPos3D p){
	return contains(p.getX(),p.getY(),p.getZ());
}

}
